﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;
using Core;
using Core.UIItems;
using Core.UIItems.ListBoxItems;
using Core.UIItems.WindowItems;
using System.Diagnostics;


namespace UITestSuite
{
    /// <summary>
    /// Test Suite for Forums Client behavior when internet connectivity is lost
    /// </summary>
    [TestFixture]
    public class LostInternetConnectivityTests
    {
        private Application applicationUnderTest;
        private Window mainWindow;
        private TestParameters testParameters;

        private Window subscriptionDialogWindow;
        private Button finishButton;
        private ComboBox brandComboBox;
        private ListView availableForumsListBox;
        private Button addButton;
        private TextBox filterTextBox;

        /// <summary>
        /// Before each test, get the test parameters and delete offline store
        /// </summary>
        [SetUp]
        public void Setup()
        {
            testParameters = new TestParameters();
            UITestHelperClass.DeleteUserConfigFile();
            UITestHelperClass.DeleteOfflineStore(testParameters.StandardDataStoreFolderName, testParameters.CustomDataStoreFileName);
        }


        /// <summary>
        /// If the test fails, it might leave the app running so we check and 
        /// shut it down (if necessary)in the teardown 
        /// </summary>
        [TearDown]
        public void TearDown()
        {
            if (applicationUnderTest != null && applicationUnderTest.HasExited == false)
            {
                applicationUnderTest.Kill();
            }
            InsureInterNetConnection();
        }

        /// <summary>
        /// This test verifies that the user cannot successfully logon if 
        /// internet connectivity is lost between application start and 
        /// the time the user completes the logon dialog
        /// </summary>
        [Test]
        public void CannotLogonIfInternetConnectivityIsLost()
        {

            InsureInterNetConnection();
            StartApp();
            DisconnectFromInternet();

            // This should fail and put up an error message from Live ID SDK
            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Find the error message from Live ID SDK
            Window loginDialogWindow;

            loginDialogWindow = mainWindow.ModalWindow("LiveID Login", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(loginDialogWindow);
            Window errorMessageDialogBox = loginDialogWindow.ModalWindow("Microsoft Forums Client", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(errorMessageDialogBox);

            Button okButton = errorMessageDialogBox.Get<Button>("OK");
            Assert.IsNotNull(okButton);
            okButton.Click();

            UITestHelperClass.CancelLogon(mainWindow);

            mainWindow.Close();
        }

        /// <summary>
        /// This test verifies that the application does not show the logon 
        /// dialog when internet connectivity is lost before application 
        /// start
        /// </summary>
        [Test]
        public void LogonDialogIsNotShownWithoutInternetConnectivityAtStartup()
        {
            DisconnectFromInternet();
            StartApp();

            ClickOKForNotConnectedDialog();

            mainWindow.Close();
        }

        /// <summary>
        /// This test verifies that the application prompts a user who has not 
        /// logged on if internet connectivity has been established and the 
        /// user attempts an action which requires them to be logged on 
        /// (subscribing to a forum or synchronizing a forum to which they 
        /// have previously subscribed)
        /// </summary>
        [Test]
        public void UnauthenticatedUserIsPromptedToLogonToSubscribeOrSynchronize()
        {
            DisconnectFromInternet();
            StartApp();

            ClickOKForNotConnectedDialog();

            // User must be connected and logged on to subscribe to new forums
            Button actionButton = mainWindow.Get<Button>("SubscribeButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Since the internet is disconnected, we should get an error message
            // that says we arenot connected to the internet.
            ClickOKForNotConnectedDialog();

            // The options dialog does not require either internet connection or 
            // being logged on. So, it shoudl work fine.
            actionButton = mainWindow.Get<Button>("OptionsButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            Window optionsDialogWindow = mainWindow.ModalWindow("OptionsDialog", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(optionsDialogWindow);

            CheckBox checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);

            // Uncheck the Auto Synch option check box
            if (checkBox.Checked == true)
            {
                checkBox.Click();
            }
            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Now, instruct the tester to enable internet connection
            InsureInterNetConnection();

            // After we have internet connection, the unauthenticated user 
            // should be prompted to log on to be able to Subscribe
            actionButton = mainWindow.Get<Button>("SubscribeButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            UITestHelperClass.Logon(mainWindow, testParameters.LogonInfo);

            // Now subscribe to a forum without any main UI window validation
            // of the subscription. That's covered in the Subscription Dialog 
            // tests.

            // Find the Subscription Dialog window
            subscriptionDialogWindow = (Window)mainWindow.ModalWindow("Subscribe to Forums", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(subscriptionDialogWindow);

            // Set brand to MSDN
            brandComboBox = subscriptionDialogWindow.Get<ComboBox>("BrandComboBox");
            Assert.IsNotNull(brandComboBox);
            brandComboBox.Select("Msdn");

            // Use the filter text box to reduce the number of forums displayed
            filterTextBox = subscriptionDialogWindow.Get<TextBox>("FilterTextBox");
            Assert.IsNotNull(filterTextBox);
            filterTextBox.Text = "js";

            // Select the Forum
            availableForumsListBox = subscriptionDialogWindow.Get<ListView>("AvailableForumsListView");
            Assert.IsNotNull(availableForumsListBox);
            Assert.LessOrEqual(1, availableForumsListBox.Rows.Count, "No forums after filtering with js");
            availableForumsListBox.Rows[0].Select();
            availableForumsListBox.Rows[0].Click();
            System.Threading.Thread.Sleep(500);

            // Click on the Add button
            addButton = subscriptionDialogWindow.Get<Button>("AddButton");
            Assert.IsNotNull(addButton);
            addButton.Click();
            System.Threading.Thread.Sleep(500);

            // Click the Finish button
            finishButton = subscriptionDialogWindow.Get<Button>("FinishButton");
            Assert.IsNotNull(finishButton);
            finishButton.Click();
            System.Threading.Thread.Sleep(3000);

            // Now, disable the internet, exit and restart the app
            DisconnectFromInternet();
            mainWindow.Close();

            StartApp();

            ClickOKForNotConnectedDialog();

            // User must be connected and logged on to syncronize forums
            Core.UIItems.TreeItems.Tree tree = mainWindow.Get<Core.UIItems.TreeItems.Tree>("forumTreeView");
            Assert.IsNotNull(tree);

            // This is the only way to get to the "Forums" context menu
            // Ideally, we'd be able to tell White to get "Forums" from the 
            // TreeView but, because we have StackPanel objects as the 
            // header property, WPF and UIAutomation don't cooperate
            // Forunately, we have a standard order of items in the 
            // TreeView down to the Forums header
            tree.Nodes[0].Nodes[1].RightClick();
            Assert.IsTrue(mainWindow.HasPopup(), "No context menu after right click");

            Core.UIItems.MenuItems.Menu menu = mainWindow.PopupMenu("Synchronize All");
            Assert.IsNotNull(menu, "Synchronize All is not in context menu");

            menu.Click();

            ClickOKForNotConnectedDialog();

            // Have the tester enable the internet connection
            InsureInterNetConnection();

            // Click the Synchronize All context menu item again
            tree.Nodes[0].Nodes[1].RightClick();
            Assert.IsTrue(mainWindow.HasPopup(), "No context menu after right click");
            menu = mainWindow.PopupMenu("Synchronize All");
            Assert.IsNotNull(menu, "Synchronize All is not in context menu");

            menu.Click();

            // This should bring up the Logon Dialog. 
            // Just cancel it and exit the app
            UITestHelperClass.CancelLogon(mainWindow);
            mainWindow.Close();
        }

        #region Private Methods
        /// <summary>
        /// Instructs the tester to connect to internet
        /// </summary>
        private void InsureInterNetConnection()
        {
            System.Windows.MessageBox.Show("Enable Internet connection");           
        }

        /// <summary>
        /// Instructs the tester to disconnect to internet
        /// </summary>
        private void DisconnectFromInternet()
        {
            System.Windows.MessageBox.Show("Disable or disconnect all internet connections.");
        }

        /// <summary>
        /// Start the App and get the main window
        /// </summary>
        private void StartApp()
        {
            applicationUnderTest = Application.Launch("ForumsClient.exe");
            mainWindow = (Window)applicationUnderTest.GetWindow(UITestSuiteStringResourceFile.MicrosoftForumsClientBuildName, Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(mainWindow);
        }

        private void ClickOKForNotConnectedDialog()
        {
            Window errorMessageDialogBox;
            Button okButton;

            errorMessageDialogBox = mainWindow.ModalWindow("Not Connected", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(errorMessageDialogBox);
            okButton = errorMessageDialogBox.Get<Button>("OK");
            Assert.IsNotNull(okButton);
            okButton.Click();
        }
        #endregion

    }
}
